#include <prism/frontend/semantic_analysis/semantic_analysis.hpp>
//=====================================================================
#include <boost/bind.hpp>
//=====================================================================
#include <sooty/frontend/syntactic_analysis/algorithm.hpp>
//=====================================================================
#include <prism/frontend/syntactical_analysis/marshall.hpp>
#include <prism/frontend/semantic_analysis/resolve/function.hpp>
//=====================================================================

//=====================================================================
// predicate for sorting functions in order of scope resolution.
//  - if we find any equivalence, then we have an ambiguity at that level.
//=====================================================================
struct function_pred
{
	bool operator ()(sooty::const_parseme_ptr_ref lhs, sooty::const_parseme_ptr_ref rhs) const
	{
		ATMA_ASSERT(lhs->id == prism::ID::function);
		ATMA_ASSERT(rhs->id == prism::ID::function);
		
		// first, sort by depth of tree
		int lhs_depth = sooty::distance(lhs);
		int rhs_depth = sooty::distance(rhs);
		
		if (lhs_depth < rhs_depth)
			return true;
		else if (rhs_depth < lhs_depth)
			return false;
		else
			ATMA_HALT("bad < operator");
		
		return false;
	}
};


void prism::semantic_analysis::function(const semantic_info& info, sooty::parseme_ptr_ref N)
{
	//=====================================================================
	// 0) get stuff
	//=====================================================================
	sooty::parseme_ptr_ref name = marshall::function::name(N);
	sooty::parseme_ptr_ref parameter_list = marshall::function::parameter_list(N);
	sooty::parseme_ptr_ref return_type = marshall::function::return_type(N);
	sooty::parseme_ptr_ref body = marshall::function::body(N);
	
	
	//=====================================================================
	// 1) check for ambiguities
	//=====================================================================
	sooty::parseme_container matching_functions;
	sooty::upwards_bredth_first_copy_if(N, std::back_inserter(matching_functions), prism::resolve::function_matches_function_pred(N));
	std::sort(matching_functions.begin(), matching_functions.end(), function_pred());
	
}